﻿function validate(obj) {
    var rules = obj.rules;
    var messages = obj.messages;

    var temErros = false;

    $('span.validate-message').siblings().removeClass('input-validation-error').end().remove();

    for (var itemRegra in rules) {
        var tag = $('#' + itemRegra);
        // Se a tag não existe, pulamos
        if (tag.length == 0) continue;

        var val = $.trim(tag.val());
        var msgs = messages[itemRegra];
        if (msgs == undefined) msgs = {};
        var regra = rules[itemRegra];

        // É required?
        if (regra['required'] == true) {
            if (val == '') {
                exibeErro(tag, (msgs['required'] != undefined ? msgs['required'] : "Campo requerido"));
                changeBind(tag);
                temErros = true;
            }
        }

        // É minlength?
        if (regra['minlength'] != undefined) {
            var tamanho = regra['minlength'];
            if (val.length < tamanho && val != '') {
                exibeErro(tag, (msgs['minlength'] != undefined ? msgs['minlength'] : "Campo deve ter pelo menos " + tamanho + " caracteres"));
                changeBind(tag);
                temErros = true;
            }
        }

        // É digits?
        if (regra['digits'] == true && val != '') {
            var numbers = /^\d+$/;
            var isValid = numbers.test(val);
            if (!isValid && val != '') {
                exibeErro(tag, (msgs['digits'] != undefined ? msgs['digits'] : "Campo deve conter apenas números"));
                changeBind(tag);
                temErros = true;
            }
        }

        // É telefone?
        if (regra['phone'] == true & val != '') {
            var phones = /^(\(\d{2}\)) \d{4,5}\-\d{3,4}$/;
            var isValid = phones.test(val);
            if (!isValid && val != '') {
                exibeErro(tag, (msgs['phone'] != undefined ? msgs['phone'] : "Campo deve conter um número de telefone válido"));
                changeBind(tag);
                temErros = true;
            }
        }

        // É data?
        if (regra['date'] == true & val != '') {
            var validDate = /^((((0?[1-9]|[12]\d|3[01])[\.\-\/](0?[13578]|1[02])[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}))|((0?[1-9]|[12]\d|30)[\.\-\/](0?[13456789]|1[012])[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}))|((0?[1-9]|1\d|2[0-8])[\.\-\/]0?2[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}))|(29[\.\-\/]0?2[\.\-\/]((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00)))|(((0[1-9]|[12]\d|3[01])(0[13578]|1[02])((1[6-9]|[2-9]\d)?\d{2}))|((0[1-9]|[12]\d|30)(0[13456789]|1[012])((1[6-9]|[2-9]\d)?\d{2}))|((0[1-9]|1\d|2[0-8])02((1[6-9]|[2-9]\d)?\d{2}))|(2902((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00))))$/;
            var isValid = validDate.test(val);
            if (!isValid && val != '') {
                exibeErro(tag, (msgs['digits'] != undefined ? msgs['digits'] : "Campo deve conter uma data válida"));
                changeBind(tag);
                temErros = true;
            }
        }

        // É e-mail?
        if (regra['email'] == true & val != '') {
            var validEmail = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
            var isValid = validEmail.test(val);
            if (!isValid && val != '') {
                exibeErro(tag, (msgs['digits'] != undefined ? msgs['digits'] : "Campo deve conter um e-mail válido"));
                changeBind(tag);
                temErros = true;
            }
        }

        // É twins
        if (regra['twins'] != undefined) {
            var twins = false;
            for (sibling in regra['twins']) {
                if ($('#' + regra['twins'][sibling]).val() != '') twins = true;
            }
            if (!twins) {
                exibeErro(tag, (msgs['twins'] != undefined ? msgs['twins'] : "Pelo menos um campo deve ser preenchido"));
                changeBindTwins(tag, regra['twins']);
                temErros = true;
            }
        }

        // É personalizado
        if (regra['custom'] != undefined) {
            var menu = window[regra['custom']](tag);
            if (!menu) {
                exibeErro(tag, (msgs['custom'] != undefined ? msgs['custom'] : "Campo inválido"));
                changeBind(tag);
                temErros = true;
            }
        }
    }

    return !temErros;
}

function exibeErro(obj, text) {
    obj.addClass('input-validation-error');
    var spanErro = $('<span/>').addClass('text-danger').addClass('validate-message').html(text).append('<br />');
    obj.after(spanErro);
}

function changeBind(obj) {
    obj.on('change', function () {
        $(this).removeClass('input-validation-error');
        $(this).siblings('span.validate-message').remove();
    });
    obj.on('blur', function () {
        $(this).removeClass('input-validation-error');
        $(this).siblings('span.validate-message').remove();
    });
}

function changeBindTwins(obj, twins) {
    obj.on('change', function () {
        for (sibling in twins) {
            var item = $(twins[sibling]);
            item.removeClass('input-validation-error').siblings('span.validate-message').remove();
        }
    });
    obj.on('blur', function () {
        for (sibling in twins) {
            var item = $(twins[sibling]);
            item.removeClass('input-validation-error').siblings('span.validate-message').remove();
        }
    });
}
